import fetch from 'dva/fetch';
import moment from 'moment';
import { message } from 'antd';
import { isSuccess } from '@/utils/request';
import { getFlowByType } from './services';

export const request = (path, param, option = {}) => {
    const myHeaders = new Headers();
    myHeaders.append('Content-Type', 'application/json');

    const raw = JSON.stringify(param);

    const requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: raw,
        ...option
    };

    return new Promise(resolve => {
        fetch(path, requestOptions)
            .then(response => response.json())
            .then(result => resolve(result))
            .catch(error => console.log('error', error));
    });
};

/**
 *
 * @param {Object} hasMomentObject 带moment对象的form表单
 * @description 将带moment格式对象的object中的moment转换为时间字符串，方便提交给后端
 */
export const objMomentFormat = (hasMomentObject = {}) => {
    if (Object.prototype.toString.call(hasMomentObject) === '[object Object]') {
        const tempObj = hasMomentObject;
        const format = 'YYYY-MM-DD HH:mm:ss';
        Object.entries(tempObj).forEach(item => {
            const key = item[0];
            let value = item[1];

            if (moment.isMoment(value)) {
                value = value.format(format);
                tempObj[key] = value;
            }
            // 判断是否为数组
            if (Array.isArray(value)) {
                const arr = value.map(subItem => {
                    if (moment.isMoment(subItem)) {
                        return subItem.format(format);
                    }
                    return subItem;
                });

                tempObj[key] = arr;
            }
        });
        return tempObj;
    }
    return hasMomentObject;
};

// 时间格式处理
const formatMap = {
    Date: {
        yearTime: 'YYYY-MM-DD HH:mm:ss',
        month: 'YYYY-MM',
        hourMinute: 'YYYY-MM-DD HH:mm',
        default: 'YYYY-MM-DD'
    },
    RangePicker: {
        yearPricker: 'YYYY-MM-DD',
        hourPricker: 'YYYY-MM-DD HH:mm:ss',
        hourMinutePricker: 'YYYY-MM-DD HH:mm',
        default: 'YYYY-MM-DD'
    },
    TimePicker: {
        default: 'HH:mm:ss'
    }
};

/**
 *
 * @param {Array} formList 流程组件集合
 * @param {Object} values 组件的表单值集合
 */
export const getSummary = (formList = [], values = {}) => {
    const summaryArr = [];
    const summaryJson = [];
    const recFn = node => {
        if (Array.isArray(node)) {
            node.forEach(item => {
                const { isSummary, label, formId, tag, dataType, pickerType, children } = item;
                if (isSummary === true) {
                    let v = values[formId];
                    if (v) {
                        let obj = {};
                        const format = formatMap[tag]?.[dataType || pickerType] || formatMap[tag]?.default;

                        // 坑爹的处理方式，联系人，请假类型等下拉类型的数据值返回value，得不到label只能通过dom拿值
                        const tagValueFromDom = ['ContactsInput', 'LeaveType', 'InstitutionType'];
                        if (tagValueFromDom.includes(tag)) {
                            v = document.querySelector(`#${formId} .ant-select-selection-selected-value`).textContent;
                        }

                        // 又一种情况，label和key分开两个字段存，key和keyName这种模式的，读取keyName的值!!!
                        const vName = values[`${formId}Name`];
                        if (v && vName) {
                            v = vName;
                        }

                        // 处理时间组件
                        if (moment.isMoment(v)) {
                            v = v.format(format);
                        } else if (Object.prototype.toString.call(v) === '[object Object]') {
                            // 又是另一种情况，另外的时间对象...
                            if (v?.time) {
                                if (moment.isMoment(v?.time)) {
                                    v = v?.time.format(format);
                                }
                            } else {
                                // 如果是个对象尝试读取label
                                v = v?.label || v?.value;
                            }
                        } else if (Array.isArray(v)) {
                            // 判断是否为数组
                            const arr = v.map(subItem => {
                                if (moment.isMoment(subItem) || format) {
                                    // 审批的时候日期是字符串！根据format判断是日期
                                    return typeof subItem === 'string'
                                        ? moment(subItem).format(format)
                                        : subItem.format(format);
                                }
                                if (Object.prototype.toString.call(subItem) === '[object Object]') {
                                    // 如果是个对象尝试读取label
                                    return subItem?.label;
                                }
                                return subItem;
                            });
                            v = arr;
                        } else if (!Array.isArray(v) && format) {
                            // 审批时间问题
                            v = moment(v).format(format);
                        }

                        obj = `${[label]}: ${v}`;
                        summaryArr.push(obj);
                        summaryJson.push({ itemName: label, itemValue: Array.isArray(v) ? v.join(',') : v });
                    }
                }
                if (children) {
                    recFn(children);
                }
            });
        }
    };
    recFn(formList);
    if (summaryArr.length > 0) {
        return [summaryArr.join('<br/>'), summaryJson];
    }
    return [];
};

/**
 *
 * @param {String} str 特殊处理其他业务摘要不统一问题
 */
export const stringToSummary = str => {
    const summaryJson = [];
    if (str) {
        const arr = str.split('<br />');
        if (arr.length > 0) {
            arr.forEach(item => {
                const itemArr = item.split(':');
                if (itemArr.length > 0) {
                    summaryJson.push({ itemName: itemArr[0], itemValue: itemArr[1].trim() });
                }
            });
        }
    }
    return [str, summaryJson];
};

/**
 *
 * 生成唯一id
 */
export function genID(length) {
    return Number(
        Math.random()
            .toString()
            .substr(3, length) + Date.now()
    ).toString(36);
}

/**
 *
 * @param {String} flowType 流程类型
 * @param {Boolean} showErr 是否提示错误信息，默认true
 * @param {Object} draftObj 暂存草稿的{bizType:"", bizKey:""}
 * @returns {Object} 返回的对象workFlowUrl：申请url，请在添加历史记录完成后追加id值；workFlowErrorMsg：错误信息；如果需要新页签打开可以使用workFlowPathname和workFlowQuery
 */
export const hasWorkFlowByType = async (flowType, showErr = true, draftObj = {}) => {
    // 验证流程是否存在
    const { msg, code, data = {} } = await getFlowByType(flowType);
    if (code === 10000) {
        return new Promise(resolve => {
            const { actProcessDefinitionId, processName } = data;
            const { bizType, bizKey } = draftObj;
            let workFlowUrl = '';
            let workFlowPathname = '';
            let workFlowQuery = {};
            // 拼接固定的参数
            workFlowUrl = `/personal/portal/apply?id=${actProcessDefinitionId}&name=${processName}&bizType=${bizType}&bizKey=${bizKey}&hiDataId=`;
            workFlowQuery = { id: actProcessDefinitionId, name: processName, bizType, bizKey, hiDataId: null };
            workFlowPathname = '/personal/portal/apply';
            resolve({ workFlowUrl, workFlowPathname, workFlowQuery, workFlowErrorMsg: msg });
        });
    }
    return new Promise(reject => {
        if (showErr) {
            message.error(msg);
        }
        reject({ workFlowErrorMsg: msg });
    });
};

/**
 *
 * @param {String} processInstanceId 流程id
 * @description 调整到流程抄送详情
 */
export const gotoWorkFlowDetail = applicationNo =>
    `/personal/portal/myAuditRead/myAuditReadDetail?applicationNo=${applicationNo}`;

/**
 * 根据流程分类来获取流程信息，50013(代表流程不存在)
 * @param {string} flowType 流程分类
 * @param {boolean} showError 是否显示信息信息
 * @returns {Promise<unknown>}
 */
export const getWorkFlowByType = (flowType, showError) =>
    new Promise((resolve, reject) => {
        // 验证流程是否存在
        getFlowByType(flowType)
            .then(response => {
                if (isSuccess(response)) {
                    const { actProcessDefinitionId, processName } = response.data;
                    const workFlowUrl = `/personal/portal/apply?id=${actProcessDefinitionId}&name=${processName}&hiDataId=`;
                    resolve({
                        ...response.data,
                        workFlowUrl
                    });
                } else if (response.code === 50013) {
                    // 流程不存在
                    resolve(null);
                } else {
                    if (showError) {
                        message.error(response.msg);
                    }
                    reject(response.msg);
                }
            })
            .catch(e => {
                reject(e);
            });
    });
